package org.arain.baseii.websocket;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.arain.baseii.connect.ConnectService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;  
  
public class SystemWebSocketHandler implements WebSocketHandler {  
    @Autowired
    private ConnectService connectService;
	
    private Logger log = LoggerFactory.getLogger(SystemWebSocketHandler.class);  
      
    private static final Map<WebSocketSession,String> users = new LinkedHashMap<>();
    
   
    @Override  
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
    	String user = (String) session.getAttributes().get(Constants.DEFAULT_WEBSOCKET_USERNAME);
         users.put(session,user);
         System.out.println(user + " connect success ...");
          
    }  
   
    @Override  
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {  
        System.out.println("handleMessage" + message.toString());  
        log.debug("handleMessage" + message.toString());  
        for (Map.Entry<WebSocketSession,String> entry : users.entrySet()) {
        	String user = entry.getValue();
        	if(StringUtils.isNotBlank(user)) {
        		JSONArray array = new JSONArray();
        		JSONObject out = new JSONObject();
        		   for (Map.Entry<WebSocketSession,String> entry2 : users.entrySet()) {
        	        	String user2 = entry2.getValue();
        	        	if(StringUtils.isNotBlank(user2)) {
        	        		Integer integer = connectService.load_unread(user, user2);
        	        		JSONObject object = new JSONObject();
        	        		object.put("name", user2);
        	        		object.put("unread", integer);
        	        		array.add(object);
        	        	}
        	        }
        		   	out.put("data", array);
        	        out.put("count", users.size());
        	        sendMessageToUser(user,new TextMessage(out.toString()));
        	}
          }
    }  
   
    @Override  
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {  
        if(session.isOpen()){  
            session.close();  
        }  
        String user = (String) session.getAttributes().get(Constants.DEFAULT_WEBSOCKET_USERNAME);
        users.remove(session,user);  
          
        log.debug("handleTransportError" + exception.getMessage());  
    }  
   
    @Override  
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {  
    	String username = (String) session.getAttributes().get(Constants.DEFAULT_WEBSOCKET_USERNAME);
         users.remove(session,username);  
         for (Map.Entry<WebSocketSession,String> entry : users.entrySet()) {
         	String user = entry.getValue();
         	if(StringUtils.isNotBlank(user)) {
         		JSONArray array = new JSONArray();
         		JSONObject out = new JSONObject();
         		   for (Map.Entry<WebSocketSession,String> entry2 : users.entrySet()) {
         	        	String user2 = entry2.getValue();
         	        	if(StringUtils.isNotBlank(user2)) {
         	        		Integer integer = connectService.load_unread(user, user2);
         	        		JSONObject object = new JSONObject();
         	        		object.put("name", user2);
         	        		object.put("unread", integer);
         	        		array.add(object);
         	        	}
         	        }
         		   	out.put("data", array);
         	        out.put("count", users.size());
         	        sendMessageToUser(user,new TextMessage(out.toString()));
         	}
         }
    }  
 
    @Override  
    public boolean supportsPartialMessages() {  
        return false;  
    }  
   
    /** 
     * 给所有在线用户发送消息 
     * 
     * @param message 
     */  
    public void sendMessageToUser(String username, TextMessage message) {
    	 Iterator<Map.Entry<WebSocketSession, String>> it = userIterator();
        while (it.hasNext()) {
            WebSocketSession session = it.next().getKey();
            String user = (String) session.getAttributes().get(Constants.DEFAULT_WEBSOCKET_USERNAME);
            if (username.equals(user)) {
                try {
                    if (session.isOpen())
                        session.sendMessage(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    
    public void sendMessageToUsers(TextMessage message) {
        Iterator<Map.Entry<WebSocketSession, String>> it = userIterator();
        while (it.hasNext()) {
            WebSocketSession session = it.next().getKey();
            try {
                if (session.isOpen())
                    session.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    private Iterator<Map.Entry<WebSocketSession, String>> userIterator() {
        Set<Map.Entry<WebSocketSession,String>> entrys = users.entrySet();
        return entrys.iterator();
    }
    
    
    public void refresh(ConnectService service,String username) {
    	JSONArray array = new JSONArray();
  		JSONObject out = new JSONObject();
    	 for (Map.Entry<WebSocketSession,String> entry : users.entrySet()) {
          	String user = entry.getValue();
          	if(StringUtils.isNotBlank(user)) {
          			Integer integer = service.load_unread(username, user);
	        		JSONObject object = new JSONObject();
	        		object.put("name", user);
	        		object.put("unread", integer);
	        		array.add(object);
          		}
    	 }
    		out.put("data", array);
  	        out.put("count", users.size());
  	        sendMessageToUser(username,new TextMessage(out.toString()));
    }
    
}  